package cn.edu.gdu.quizpractice.common.utils;

import cn.edu.gdu.quizpractice.dao.ChoiceQuestionDao;
import cn.edu.gdu.quizpractice.entity.ChoiceQuestion;
import cn.edu.gdu.quizpractice.common.exception.ExcelImportException;
import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.event.AnalysisEventListener;
import lombok.extern.slf4j.Slf4j;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;

/**
 * @Author: Aubery
 * @Date: 2025-03-22-9:54
 * @Description:
 * 
 * 错误"找不到符号:变量log"的解决方法:
 * 1. 在IntelliJ IDEA中，打开File > Settings > Build, Execution, Deployment >
 *                             Compiler > Shared build process VM options
 * 2. 添加参数: -Djps.track.ap.dependencies=false
 * 3. 重新构建项目
 */
@Slf4j
@Component
@Transactional
public class ChoiceQuestionExcelListener extends AnalysisEventListener<ChoiceQuestion> {

    // 如果@Slf4j注解不生效，请使用以下方式创建日志记录器
    //private static final Logger log = LoggerFactory.getLogger(ChoiceQuestionExcelListener.class);
    private static final int BATCH_SIZE = 200;

    private final ChoiceQuestionDao choiceQuestionDao;
    private List<ChoiceQuestion> cachedList = new ArrayList<>(BATCH_SIZE);
    private List<String> errorMessages = new ArrayList<>();

    public ChoiceQuestionExcelListener(ChoiceQuestionDao choiceQuestionDao) {
        this.choiceQuestionDao = choiceQuestionDao;
    }

    @Override
    public void invoke(ChoiceQuestion question, AnalysisContext context) {
        log.info("读取到数据: {}", question.getCqContent());
        try {
            // 确保 difficulty 是整数
            if (question.getDifficulty() != null) {
                question.setDifficulty(Integer.parseInt(question.getDifficulty().toString()));
            }
            // 确保 isMultiple 是布尔值
            if (question.getIsMultiple() != null) {
                question.setIsMultiple(Boolean.parseBoolean(question.getIsMultiple().toString()));
            }
            validateQuestion(question);  // 数据校验
            cachedList.add(question);
            if (cachedList.size() >= BATCH_SIZE) {
                saveBatch();
                cachedList.clear();
            }
        } catch (Exception e) {
            int row = context.readRowHolder().getRowIndex() + 1; // Excel行号从0开始
            errorMessages.add("第" + row + "行错误: " + e.getMessage());
        }
    }

    @Override
    public void doAfterAllAnalysed(AnalysisContext context) {
        if (!cachedList.isEmpty()) {
            saveBatch();
        }
        if (!errorMessages.isEmpty()) {
            throw new ExcelImportException("部分数据导入失败:\n" + String.join("\n", errorMessages));
        }
    }

    @Transactional
    protected void saveBatch() {
        if (cachedList.isEmpty()) {
            return;
        }
        log.info("开始批量插入 {} 条数据", cachedList.size());
        try {
            int i = choiceQuestionDao.insertBatch(cachedList);
            log.info("插入的条数为：{}", i);
            if (i == cachedList.size()) {
                log.info("批量插入成功");
            } else {
                log.info("批量插入失败");
                throw new RuntimeException("批量插入失败，预期插入 " + cachedList.size() + " 条，实际插入 " + i + " 条");
            }
        } catch (Exception e) {
            log.error("批量插入异常", e);
            throw new RuntimeException("批量插入异常: " + e.getMessage());
        }
    }

    /**
     * 自定义数据校验逻辑
     */
    private void validateQuestion(ChoiceQuestion question) {
        if (question.getIsMultiple() && question.getCorrectAnswer().length() < 2) {
            throw new IllegalArgumentException("多选题正确答案至少需要两个选项");
        }
        // 其他校验逻辑...
    }
}
